/**
 * Solver.cpp
 * Coyright (c) 2009 Xiaofeng Gu. All Rights Reserved.
 * Author : Xiaofeng Gu
 *
 * Creation Data : 2009/06/11
 */

#include "stdafx.h"
#include "Solver.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

HRESULT CSolver::OnExecute()
{
	HRESULT hr = S_OK;
	hr = __super::OnExecute();
	if (hr != S_OK)
	{
		return hr;
	}

	CSolverProcessCard* pSolverProcessCard = GetBlockInfo<CSolverProcessCard>(SOLVERPROCESSCARD);
	Families* pFamiles = pSolverProcessCard->GetFamilies();
	for (Families::iterator itFa = pFamiles->begin(); itFa != pFamiles->end(); itFa ++)
	{
		CFamily* pFamily = *itFa;
		Knots* pKnots = pFamily->GetKnots();
		m_pFrames = pFamily->GetFrames();
		pFamily->ClearFrames();

		long lCount = (long)(pKnots->size());
		for (long i = 0; i < lCount-1; i ++)
		{
			CKnot* pKnot = (*pKnots)[i];
			pKnot->Back();
			Solve(pKnot);
			pKnot->Rollback();
		}
	}

	return S_OK;
}

void CSolver::Solve(CKnot* pKnot)
{
	CTransNode* pTopNode = pKnot->GetTopNode();
	CTransPath* pPath = pKnot->GetPath();
	Path3d* pPath3d = pPath->GetPath();
	long lPathCount = (long)(pPath3d->size());
	lPathCount /= 3;
	for(long lIndex = 0; lIndex < lPathCount; lIndex ++)
	{
		Solve(pKnot, pPath3d, lIndex);
	}
}

void CSolver::Solve(CKnot* pKnot, Path3d* pPath3d, long lIndex)
{
	CTransNode* pTopNode = pKnot->GetTopNode();
	CVec moveToPt = CVec((*pPath3d)[3*lIndex + 0], (*pPath3d)[3*lIndex + 1], (*pPath3d)[3*lIndex + 2]);
	pTopNode->MoveTo(moveToPt);

	CFrame* pFrame = new CFrame();
	m_pFrames->push_back(pFrame);
	Nodes* pNodes = pKnot->GetNodes();
	for (Nodes::iterator it = pNodes->begin();
		it != pNodes->end(); it ++)
	{
		CTransNode* pNode = *it;
		if (lIndex != 0)
			++(*pNode);

		CBone* pBone = pNode->GetBone();
		Streams* pStreams = pFrame->GetStreams();
		pStreams->push_back((*pBone)[0][0]);
		pStreams->push_back((*pBone)[0][1]);
		pStreams->push_back((*pBone)[0][2]);
		pStreams->push_back((*pBone)[1][0]);
		pStreams->push_back((*pBone)[1][1]);
		pStreams->push_back((*pBone)[1][2]);
	}
}